﻿using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;
using System.Drawing;
using System.Linq;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Design;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Serialization;
using System.Workflow.Runtime;
using System.Workflow.Activities;
using System.Workflow.Activities.Rules;
using CommonWFLibrary;
using IndicoInterface;
using System.Xml.Serialization;
using System.IO;
using IndicoInterface.SimpleAgendaDataModel;

namespace DeepTalkWF
{
    /// <summary>
    /// Fetch the agenda given XML to inflate an Agenda-like object or interface.
    /// </summary>
	public partial class GetAgenda: LongRunningActivityBase
	{
		public GetAgenda()
		{
			InitializeComponent();
            TimesToRetry = 10;
		}

        /// <summary>
        /// The XML that specifies the Agenda that we need to fetch and get the
        /// normalized Meeting data for.
        /// </summary>
        public string AgendaXML
        {
            get { return (string)GetValue(AgendaXMLProperty); }
            set { SetValue(AgendaXMLProperty, value); }
        }

        // Using a DependencyProperty as the backing store for AgendaXML.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty AgendaXMLProperty =
            DependencyProperty.Register("AgendaXML", typeof(string), typeof(GetAgenda), new PropertyMetadata(null));

        /// <summary>
        /// The resulting normalized Meeting info we have downloaded from the agenda server.
        /// </summary>
        public Meeting MeetingInfo
        {
            get { return (Meeting)GetValue(MeetingInfoProperty); }
            set { SetValue(MeetingInfoProperty, value); }
        }

        // Using a DependencyProperty as the backing store for MeetingInfo.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MeetingInfoProperty =
            DependencyProperty.Register("MeetingInfo", typeof(Meeting), typeof(GetAgenda), new PropertyMetadata(null));

        /// <summary>
        /// Title of the meeting
        /// </summary>
        public string Title
        {
            get { return (string)GetValue(TitleProperty); }
            set { SetValue(TitleProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Title.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty TitleProperty =
            DependencyProperty.Register("Title", typeof(string), typeof(GetAgenda), new PropertyMetadata(null));

        /// <summary>
        /// The time the meeting will start
        /// </summary>
        public DateTime StartTime
        {
            get { return (DateTime)GetValue(StartTimeProperty); }
            set { SetValue(StartTimeProperty, value); }
        }

        // Using a DependencyProperty as the backing store for StartTime.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty StartTimeProperty =
            DependencyProperty.Register("StartTime", typeof(DateTime), typeof(GetAgenda), new PropertyMetadata(DateTime.Now));

        /// <summary>
        /// Hold the stuff we will have run in the long-running activity.
        /// </summary>
        [Serializable]
        public class Args
        {
            public string _agenda_xml;
        }

        /// <summary>
        /// The returning info from our run.
        /// </summary>
        [Serializable]
        public class Results
        {
            public Meeting _m;
        }

        /// <summary>
        /// Fluff and unfluff the AgendaXML dude.
        /// </summary>
        private static XmlSerializer _agendaSer = new XmlSerializer (typeof(AgendaInfo));

        /// <summary>
        /// Package up the arguments to forward to the long running dude.
        /// </summary>
        /// <returns></returns>
        [LongRunningGatherArguments]
        public Args Gather()
        {
            Args a = new Args();
            a._agenda_xml = AgendaXML;
            return a;
        }

        [LongRunningMethod]
        public static Results DownloadAgenda(Args c)
        {
            AgendaInfo info = _agendaSer.Deserialize(new StringReader(c._agenda_xml)) as AgendaInfo;
            if (info == null)
            {
                throw new ArgumentException("The Agenda XML did not get re-fluffed to a valid Agenda object");
            }

            Meeting m = info.GetNormalizedConferenceData();

            Results r = new Results();
            r._m = m;

            return r;
        }

        /// <summary>
        /// Ok -- stick the results back in for all to use!
        /// </summary>
        /// <param name="r"></param>
        [LongRunningDistributeArguments]
        public void Distribute(Results r)
        {
            MeetingInfo = r._m;
            Title = r._m.Title;
            StartTime = r._m.StartDate;
        }
	}
}
